
(function ($) {
    $.fn.yqCacheEdit = function (opts, param) {
        if (typeof opts == 'string') {
            return $.fn.yqCacheEdit.methods[opts](this, param);
        }

        return this.each(function () {
            var $this = $(this);
            var opt;
            if ($this.data("yqtype") == "yqCacheEdit") {
                var $uniqueID = $this.attr("ID");
                var opts_ = $.extend({}, options($this));
                //destroy($this);
                $this = $("#" + $uniqueID);
                opt = $.extend(opts_, opts);
            }
            else {
                opt = $.extend({}, $.fn.yqCacheEdit.defaults, opts);
                var $uniqueID = $this.attr("ID");
                if ($uniqueID === undefined || $uniqueID === null || $uniqueID == "") {
                    $uniqueID = $.getUniqueID();
                    $this.attr("ID", $uniqueID);
                }
            }

            if (opt.width === undefined && $this.width() > 0) {
                opt.width = $this.width();
            }
            else if (typeof opt.width != "undefined") {
                $this.width(opt.width);
            }

            if (opt.height === undefined && $this.height() > 0) {
                opt.height = $this.height();
            }
            else if (typeof opt.height != "undefined") {
                $this.height(opt.height);
            }

            opt.data = [];

            //变量信息
            $this.data("cacheedit_opt", opt);
            $this.data("yqtype", "yqCacheEdit");

            init_ui($this);
        });
    };

    $.fn.yqCacheEdit.defaults = {
        isEdit: true,   //可编辑
        pagesize: 10,
        pageno: 1,
        afterBindingTitle: function () { },   //标题绑定后
    };

    $.fn.yqCacheEdit.methods = {
        options: function (jq) {
            return options($(jq[0]));
        },
        destroy: function (jq) {
            destroy($(jq[0]));
        },
        resize: function (jq, params) {
            onresize($(jq[0]), params);
        },
        disable: function (jq) {
            isEdit($(jq[0]), false);
        },
        enable: function (jq) {
            isEdit($(jq[0]), true);
        },
    };

    function options($object) {
        return $object.data("cacheedit_opt");
    }

    function form_load($object) {
        var $uniqueID = $object.attr("id");
        var opt = options($object);

        onresize($object);

        var $west = $("#" + $uniqueID + "_layout").layout("panel", "west");
        $west.panel("options").onResize = function (width, height) {
            if (opt.setResizeTime === undefined) {
                opt.setResizeTime = setTimeout(function () {
                    onresize($object);
                }, 100);
            }
        };

        opt.afterBindingTitle.call($object);   //标题绑定后

        getdata($object);
    };

    function onresize($object, params) {
        var $uniqueID = $object.attr("id");
        var opt = options($object);

        if (typeof params == "object") {
            opt.width = params.width;
            opt.height = params.height;
        }

        $("#" + $uniqueID + "_layout").layout('resize', {
            width: opt.width,
            height: opt.height
        });

        var $center = $("#" + $uniqueID + "_layout").layout("panel", "center");

        $("#" + $uniqueID + "_key").textbox("resize", ($center.width() - 400) < 400 ? 400 : ($center.width() - 400));

        var h_ = $center.height() - 40;
        if ($("#" + $uniqueID + "_group").checkbox("options").checked) {
            $("." + $uniqueID + "_group_view").show();

            $("#" + $uniqueID + "_group_lists").propertygrid('resize', {
                width: $center.width(),
                height: (h_ / 2 - 48)
            });

            $("#" + $uniqueID + "_subkey").textbox("resize", ($center.width() - 400) < 400 ? 400 : ($center.width() - 400));

            $("#" + $uniqueID + "_editor").yqCodeEdit('resize', {
                width: $center.width(),
                height: h_ / 2
            });
        } else {
            $("." + $uniqueID + "_group_view").hide();

            $("#" + $uniqueID + "_editor").yqCodeEdit('resize', {
                width: $center.width(),
                height: h_
            });
        }

        if (!(opt.setResizeTime === undefined)) {
            clearInterval(opt.setResizeTime);
            opt.setResizeTime = undefined;
        };
    }

    function destroy($object) {

    }

    function isEdit($object, tf) {

    }

    function init_ui($object) {
        var $uniqueID = $object.attr("id");
        var opt = options($object);

        var $body = '';
        $body += '  <div id="' + $uniqueID + '_layout" style="width:700px;height:350px;">';
        $body += '    <div data-options="region:\'west\',split:true" style="width:240px;">';
        $body += '      <div id="' + $uniqueID + '_tree" style="overflow: auto;height:100%;">';
        $body += '      </div>';
        $body += '    </div>';
        $body += '    <div data-options="region:\'center\'">';
        $body += '      <table style="padding:2px 0px 5px 0px;width:100%;">';
        $body += '        <tr>';
        $body += '          <td style="width:45px;padding-left: 5px;">key</td>';
        $body += '          <td>';
        $body += '            <input id="' + $uniqueID + '_key">';
        $body += '          </td>';
        $body += '          <td style="padding-left: 15px;">group</td>';
        $body += '          <td>';
        $body += '            <input id="' + $uniqueID + '_group">';
        $body += '          </td>';
        $body += '          <td style="padding-left: 15px;">seconds</td>';
        $body += '          <td>';
        $body += '            <input id="' + $uniqueID + '_seconds">';
        $body += '          </td>';
        $body += '          <td>';
        $body += '            <a id="' + $uniqueID + '_save" href="javascript:void(0);" title="保存"></a>';
        $body += '          </td>';
        $body += '        </tr>';
        $body += '        <tr class="' + $uniqueID + '_group_view">';
        $body += '          <td colspan="7" style="padding: 3px 0px 8px 0px;">';
        $body += '              <table  id="' + $uniqueID + '_group_lists" style="width: 90%;height:200px;"></table>';
        $body += '          </td>';
        $body += '        </tr>';
        $body += '        <tr class="' + $uniqueID + '_group_view">';
        $body += '          <td style="padding-left:5px;padding-right:5px;">subkey</td>';
        $body += '          <td>';
        $body += '            <input id="' + $uniqueID + '_subkey">';
        $body += '          </td>';
        $body += '          <td colspan="5">';
        $body += '            <div id="' + $uniqueID + '_pagination">';
        $body += '          </td>';
        $body += '        </tr>';
        $body += '      </table>';

        $body += '      <div id="' + $uniqueID + '_editor" style="margin: 5px;">some text</div>';
        $body += '    </div>';
        $body += '  </div>';

        $body += '  <div id="' + $uniqueID + '_mm">';
        $body += '    <div class="del" data-options="name:\'del\',iconCls:\'icon2-del\'">删除</div>';
        $body += '    <div class="menu-sep"></div>';
        $body += '    <div class="reload" data-options="name:\'reload\'">节点刷新</div>';
        $body += '    <div data-options="name:\'reload_all\',iconCls:\'icon2-reload\'">重新加载</div>';
        $body += '  </div>';

        $body += '  <div id="' + $uniqueID + '_mm_sub">';
        $body += '    <div class="add" data-options="name:\'add\',iconCls:\'icon2-add\'">添加</div>';
        $body += '    <div class="del" data-options="name:\'del\',iconCls:\'icon2-del\'">删除</div>';
        $body += '  </div>';

        $object.after($body);
        $object.hide();
        $("#" + $uniqueID + "_layout").layout({});
        $("#" + $uniqueID + "_key").textbox({
            width: 250
        });
        $("#" + $uniqueID + "_group").checkbox({
            checked: false,
            disabled: false,
            onChange: function (checked) {
                onresize($object);
            }
        });
        $("#" + $uniqueID + "_seconds").numberspinner({
            width: 80
        });
        $("#" + $uniqueID + "_save").linkbutton({
            width: 40,
            iconCls: "yqwin-btn-icon fa fa-floppy-o",
            onClick: function () {
                save($object);
            }
        });

        $("#" + $uniqueID + "_mm").menu({
            width: 30,
            onClick: function (item) {
                var node = $("#" + $uniqueID + "_tree").tree("getSelected");
                if (item.name == "del") {
                    node_del($object, node);
                }
                else if (item.name == "reload_all") {
                    getdata($object);
                }
                else if (item.name == "reload") {
                    if (node == null) {
                        return;
                    }

                    if (node.attributes["type"] == "path") {
                        getdata($object, node);
                    } else {
                        node_select($object, node, 1);
                    }
                } else {
                    console.log("select", item);
                }
            }
        });

        $("#" + $uniqueID + "_mm_sub").menu({
            width: 30,
            onClick: function (item) {
                console.log("select", item);
            }
        });

        init_tree($object);
    }

    function init_tree($object) {
        var $uniqueID = $object.attr("id");
        var opt = options($object);

        $("#" + $uniqueID + "_tree").tree({
            data: [],
            onContextMenu: function (e, node) {
                opt.showContextMenu = true;
                //console.log("1contextmenu");
                e.preventDefault();
                var s_node = $(this).tree("getSelected");
                if (s_node == null || s_node.attributes["path"] != node.attributes["path"]) {
                    $(this).tree('select', node.target);
                    node_select($object, node, 1);
                }
                $("#" + $uniqueID + "_mm").find('.del').removeAttr("disabled").css({
                    "cursor": "pointer",
                    "opacity": "1"
                });
                $("#" + $uniqueID + "_mm").find('.reload').removeAttr("disabled").css({
                    "cursor": "pointer",
                    "opacity": "1"
                });
                $("#" + $uniqueID + "_mm").menu('show', {
                    left: e.pageX,
                    top: e.pageY
                });
            },
            onClick: function (node) {
                node_select($object, node, 1);
            },
        });

        $("#" + $uniqueID + "_tree").bind('contextmenu', function (e) {
            if (opt.showContextMenu) {
                opt.showContextMenu = false;
                return;
            }
            //console.log("2contextmenu");
            e.preventDefault();
            $("#" + $uniqueID + "_mm").find('.del').attr("disabled", "disabled").css({ "cursor": "default", "opacity": "0.4" });
            $("#" + $uniqueID + "_mm").find('.reload').attr("disabled", "disabled").css({ "cursor": "default", "opacity": "0.4" });

            $("#" + $uniqueID + "_mm").menu('show', {
                left: e.pageX,
                top: e.pageY
            });
        });

        init_view($object);
    }

    function init_view($object) {
        var $uniqueID = $object.attr("id");
        var opt = options($object);

        $("#" + $uniqueID + "_group_lists").propertygrid({
            showGroup: false,
            fitColumns: true,
            columns: get_columns($object),
            onSelect: function (index, row) {
                //console.log(index, row["value"]);
                var val = row["value"];
                $("#" + $uniqueID + "_subkey").textbox("setValue", row["name"]);
                try {
                    var json_ = JSON.parse(val);
                    $("#" + $uniqueID + "_editor").yqCodeEdit('setType', "json");
                    $("#" + $uniqueID + "_editor").yqCodeEdit('setValue', $.jsonFormat(json_));
                } catch (e) {
                    $("#" + $uniqueID + "_editor").yqCodeEdit('setType', "txt");
                    $("#" + $uniqueID + "_editor").yqCodeEdit('setValue', val);
                }
            },
            onRowContextMenu: function (e, rowIndex, rowData) { //右键时触发事件
                //console.log(rowIndex, rowData);
                e.preventDefault();
                if (rowIndex == -1) {
                    $("#" + $uniqueID + "_mm_sub").find('.del').attr("disabled", "disabled").css({
                        "cursor": "default",
                        "opacity": "0.4"
                    });
                } else {
                    $("#" + $uniqueID + "_mm_sub").find('.del').removeAttr("disabled").css({
                        "cursor": "pointer",
                        "opacity": "1"
                    });
                }

                $("#" + $uniqueID + "_mm_sub").menu('show', {
                    left: e.pageX,
                    top: e.pageY
                });
            }
        });

        $("#" + $uniqueID + "_subkey").textbox({
            width: 250
        });

        $("#" + $uniqueID + "_pagination").pagination({
            total: 0,
            pageSize: opt.pagesize,
            showRefresh: false,
            showPageInfo: false,
            onSelectPage: function (pageNumber, pageSize) {
                var s_node = $("#" + $uniqueID + "_tree").tree("getSelected");
                node_select($object, s_node, pageNumber);
            },
            onChangePageSize: function (pageSize) {
                opt.pagesize = pageSize;
                var s_node = $("#" + $uniqueID + "_tree").tree("getSelected");
                var p_opt = $(this).pagination("options");
                node_select($object, s_node, p_opt.pageNumber);
            },
        })

        $("#" + $uniqueID + "_editor").yqCodeEdit({
            types: ["json", "txt", "html"],
            type: "json",
            value: "",
            afterBindingTitle: function () {
                form_load($object);
            },
        });
    }

    function get_columns($object) {
        var $uniqueID = $object.attr("id");

        var columns = [[
            {
                field: 'name', title: '名称',
                width: '35%'
            }, {
                field: 'value',
                title: '值',
                width: '62%',
                formatter: function (value, row, index) {
                    var escapeHtml = function (str) {
                        return str
                            .replace(/&/g, "&amp;")
                            .replace(/</g, "&lt;")
                            .replace(/>/g, "&gt;")
                            .replace(/"/g, "&quot;")
                            .replace(/'/g, "&#039;");
                    };
                    return escapeHtml(value);
                }
            }
        ]];
        return columns;
    }

    function getdata($object, node) {
        node_select($object, null, 1);

        var $uniqueID = $object.attr("id");
        var opt = options($object);

        var formData = new FormData();
        formData.append("action", "keys");
        if (typeof node == "object") {
            formData.append("path", node.id);
        }

        $.ajax({
            type: 'POST',
            url: "/_cache.html",
            data: formData,
            processData: false,
            contentType: false,
            dataType: "json",
            success: function (res) {
                console.log("keys", res);
                if ($.yqDataErrCheck(res)) {
                    if (res.error == 0) {
                        var keys = res.keys.sort();
                        var data = [];

                        if (typeof node == "object") {
                            for (var i = 0; i < opt.data.length; i++) {
                                if (opt.data[i].id.length > node.id.length) {
                                    if (opt.data[i].id.substring(0, node.id.length) != node.id) {
                                        data.push(opt.data[i]);
                                    }
                                } else {
                                    data.push(opt.data[i]);
                                }
                            }
                        }

                        keys.forEach(key => {
                            var s_key = key.value.split(":");
                            pastedata(data, s_key, 0, key);
                        });

                        opt.data = data;

                        $("#" + $uniqueID + "_tree").tree("loadData", data);

                        console.log(data);
                    } else {
                        console.log(res);
                    }
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.responseText);
                callback({ "error": 99, "info": errorThrown });
            }
        });
    }

    function node_select($object, node, pageno) {
        var $uniqueID = $object.attr("id");
        var opt = options($object);

        onresize($object);

        //console.log("selectnode", node);
        $("#" + $uniqueID + "_key").textbox("setValue", "");
        $("#" + $uniqueID + "_group").checkbox("setValue", false);
        $("#" + $uniqueID + "_seconds").numberspinner("setValue", 0);
        $("#" + $uniqueID + "_editor").yqCodeEdit('setType', "txt");
        $("#" + $uniqueID + "_editor").yqCodeEdit('setValue', "");
        $("#" + $uniqueID + "_group_lists").propertygrid("loadData", {
            "total": 0,
            "rows": []
        });
        $("#" + $uniqueID + "_subkey").textbox("setValue", "");

        if (node == null || node.attributes["type"] == "path") {
            return;
        }

        var val = node.attributes["value"];

        $("#" + $uniqueID + "_key").textbox("setValue", val.value);
        $("#" + $uniqueID + "_group").checkbox(val.group ? "check" : "uncheck");
        $("#" + $uniqueID + "_seconds").numberspinner("setValue", 0);
        $("#" + $uniqueID + "_editor").yqCodeEdit('setType', "txt");
        $("#" + $uniqueID + "_editor").yqCodeEdit('setValue', "");

        var formData = new FormData();
        formData.append("action", "info");
        formData.append("group", val.group);
        formData.append("key", val.value);

        if (val.group) {
            if (pageno === undefined) {
                pageno = 1;
            }
            opt.pageno = pageno;
            formData.append("pagesize", opt.pagesize);
            formData.append("pageno", opt.pageno);
        }

        $.ajax({
            type: 'POST',
            url: "/_cache.html",
            data: formData,
            processData: false,
            contentType: false,
            dataType: "json",
            success: function (res) {
                console.log("node info", res);
                if ($.yqDataErrCheck(res)) {
                    if (res.error == 0) {
                        $("#" + $uniqueID + "_seconds").numberspinner("setValue", res.seconds);
                        if (val.group) {
                            var rows = [];
                            for (var key in res.data) {
                                if (res.data.hasOwnProperty(key)) { // 确保是对象自有属性，不是原型链上的属性
                                    console.log(key + " -> " + res.data[key]);
                                    rows.push({
                                        "name": key,
                                        "value": res.data[key]
                                    });
                                }
                            }
                            $("#" + $uniqueID + "_group_lists").propertygrid("loadData", {
                                "total": rows.length,
                                "rows": rows
                            });

                            $("#" + $uniqueID + "_pagination").pagination('refresh', {
                                total: res.recordcount,
                                pageNumber: opt.pageno
                            });
                        } else {
                            if (typeof res.data == "object") {
                                $("#" + $uniqueID + "_editor").yqCodeEdit('setType', "json");
                                $("#" + $uniqueID + "_editor").yqCodeEdit('setValue', $.jsonFormat(res.data));
                            } else {
                                $("#" + $uniqueID + "_editor").yqCodeEdit('setType', "txt");
                                $("#" + $uniqueID + "_editor").yqCodeEdit('setValue', res.data.toString());
                            }
                        }
                    } else {
                        $.messager.show({
                            title: 'error',
                            msg: res.info + '[' + res.error + ']',
                            timeout: 3000,
                            showType: 'show'
                        });
                        console.log(res);
                    }
                }
                //console.log(res);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.responseText);
                callback({ "error": 99, "info": errorThrown });
            }
        });
    }

    //数据,用“:”切分的数据,分隔的位置,数据key
    function pastedata(data, s_key, index, key) {
        //最后一个
        if (s_key.length == (index + 1)) {
            var _id = "";
            for (var i = 0; i < s_key.length; i++) {
                _id += (_id == "" ? "" : ":") + s_key[i];
            }

            data.push({
                id: _id + (key.group ? "`" : ""),
                text: s_key[index],
                attributes: {
                    type: "key",
                    value: key
                }
            });
            return;
        }

        //不是最后一个
        for (var i = 0; i < data.length; i++) {
            if (s_key[index] == data[i].text && data[i].attributes["type"] === "path") {
                pastedata(data[i].children, s_key, index + 1, key);
                return;
            }
        }

        var path = "";
        for (var i = 0; i <= index; i++) {
            if (i == 0) {
                path = s_key[i];
            } else {
                path += ":" + s_key[i];
            }
        }

        var item = {
            id: path + ":",
            text: s_key[index],
            attributes: {
                type: "path"
            },
            children: [],
            state: "closed"
        };
        data.push(item);

        pastedata(item.children, s_key, index + 1, key);
    }

    function save($object) {
        var $uniqueID = $object.attr("id");
        var opt = options($object);

        var key = $("#" + $uniqueID + "_key").textbox("getValue");
        var seconds = $("#" + $uniqueID + "_seconds").numberspinner("getValue");
        var sub_key = null;
        var val;
        if ($("#" + $uniqueID + "_group").checkbox("options").checked) {
            sub_key = $("#" + $uniqueID + "_subkey").textbox("getValue");
        }
        var val = $("#" + $uniqueID + "_editor").yqCodeEdit('getValue');

        $.messager.show({
            title: 'todo...',
            msg: "待开发",
            timeout: 3000,
            showType: 'show'
        });

        return;

        var errInfo = "";
        if (key == "") {
            errInfo += 'key不能为空。';
        } else if (key.substr(key.length - 1, 1) == ":") {
            errInfo += 'key最末字符不能为":"。';
        }
        if (val == "") {
            errInfo += 'value不能为空。';
        }
        if (errInfo != "") {
            $.messager.show({
                title: '错误',
                msg: errInfo,
                timeout: 3000,
                showType: 'show'
            });
            return;
        }

        var formData = new FormData();
        formData.append("action", "add");
        formData.append("key", key);
        formData.append("seconds", seconds);
        formData.append("value", val);
        $.ajax({
            type: 'POST',
            url: "/_cache.html",
            data: formData,
            processData: false,
            contentType: false,
            dataType: "json",
            success: function (res) {
                if (res.error == 0) {
                    selectNode($object, key);
                    $.messager.show({
                        title: 'info',
                        msg: '执行成功。',
                        timeout: 3000,
                        showType: 'show'
                    });
                } else {
                    $.messager.show({
                        title: 'error',
                        msg: res.info + '[' + res.error + ']',
                        timeout: 3000,
                        showType: 'show'
                    });
                    console.log(res);
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.responseText);
                callback({ "error": 99, "info": errorThrown });
            }
        });
    }

    //选择节点
    function selectNode($object, key) {
        var $uniqueID = $object.attr("id");
        var opt = options($object);

        var s_key = key.split(":");
        var index = 0;
        var path = "";
        var s_node = null;
        while (index < s_key.length) {
            path += (path == "" ? "" : ":") + s_key[index];

            //key 节点
            if (index == (s_key.length - 1)) {
                var _s_node = $("#" + $uniqueID + "_tree").tree('find', key);
                if (_s_node === null) {
                    var node_data = {
                        id: key,
                        text: s_key[index],
                        attributes: {
                            type: "key",
                        }
                    };

                    if (s_node === null) {
                        $("#" + $uniqueID + "_tree").tree('append',
                            {
                                data: [node_data]
                            }
                        );
                    } else {
                        $("#" + $uniqueID + "_tree").tree('append',
                            {
                                parent: s_node.target,
                                data: [node_data]
                            }
                        );
                    }

                    _s_node = $("#" + $uniqueID + "_tree").tree('find', key);
                }

                s_node = _s_node;
                $("#" + $uniqueID + "_tree").tree('select', s_node.target);
                break;
            }

            //path 节点
            var _s_node = $("#" + $uniqueID + "_tree").tree('find', path + ":");
            if (_s_node === null) {
                var node_data = {
                    id: path + ":",
                    text: s_key[index],
                    attributes: {
                        type: "path",
                    },
                    children: [],
                    state: "open"
                };


                if (s_node === null) {
                    $("#" + $uniqueID + "_tree").tree('append',
                        {
                            data: [node_data]
                        }
                    );
                } else {
                    $("#" + $uniqueID + "_tree").tree('append',
                        {
                            parent: s_node.target,
                            data: [node_data]
                        }
                    );
                }

                _s_node = $("#" + $uniqueID + "_tree").tree('find', path + ":");
            } else {
                $("#" + $uniqueID + "_tree").tree('expand', _s_node.target);
            }
            s_node = _s_node;

            index++;
        }
    }

    function node_del($object, node) {
        node_select($object, null, 1);

        var $uniqueID = $object.attr("id");
        var opt = options($object);

        var formData = new FormData();
        formData.append("action", "predel");
        formData.append("key", (node === null ? "" : node["id"]));
        $.ajax({
            type: 'POST',
            url: "/_cache.html",
            data: formData,
            processData: false,
            contentType: false,
            dataType: "json",
            success: function (res) {
                //console.log(res);

                if (res.error == 0) {
                    if (node == null) {
                        getdata($object);
                    } else {
                        var p_node = $("#" + $uniqueID + "_tree").tree("getParent", node.target);
                        if (p_node == null) {
                            $("#" + $uniqueID + "_tree").tree("remove", node.target);
                        } else {
                            if (p_node.children.length > 1) {
                                $("#" + $uniqueID + "_tree").tree("remove", node.target);
                            } else {
                                $("#" + $uniqueID + "_tree").tree("remove", p_node.target);
                            }
                        }
                    }

                    $.messager.show({
                        title: 'info',
                        msg: '执行成功。',
                        timeout: 3000,
                        showType: 'show'
                    });
                } else {
                    $.messager.show({
                        title: 'error',
                        msg: res.info + '[' + res.error + ']',
                        timeout: 3000,
                        showType: 'show'
                    });
                    console.log(res);
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(XMLHttpRequest.responseText);
                callback({ "error": 99, "info": errorThrown });
            }
        });
    }
})(jQuery);